package net.arogarth.aws.android.lib;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.util.Log;

import net.arogarth.aws.android.lib.models.ElbInsance;
import net.arogarth.aws.android.lib.models.ElbInsance.ElbPortConfiguration;
import net.arogarth.aws.android.lib.models.ElbInsanceState;

public class AmazonElb extends AmazonAWS {
	public AmazonElb() {
		super();

//		this.setRegion("");
//		this.service = "eu-west-1.elasticloadbalancing";
		this.service = AwsSettings.getAwsRegion() + ".elasticloadbalancing";
		this.version = "2011-08-15";
	}

	public List<ElbInsance> describeLoadBalancers() throws AwsRequestException {
		List<ElbInsance> RdsDbInstances = new ArrayList<ElbInsance>();

		params.put("Action", "DescribeLoadBalancers");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//LoadBalancerDescriptions/*", root,
					XPathConstants.NODESET);

			for (int i = 0; i < items.getLength(); i++) {
				ElbInsance elbInstance = new ElbInsance();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();
					if (property.getFirstChild() == null)
						continue;
					String value = property.getFirstChild().getNodeValue();

					if (name.equalsIgnoreCase("AvailabilityZones")) {
						elbInstance.setAvailabilityZones(value);
					} else if (name.equalsIgnoreCase("CanonicalHostedZoneName")) {
						elbInstance.setCanonicalHostedZoneName(value);
					} else if (name.equalsIgnoreCase("CanonicalHostedZoneNameID")) {
						elbInstance.setCanonicalHostedZoneNameId(value);
					} else if (name.equalsIgnoreCase("CreatedTime")) {
						elbInstance.setCreatedTime(value);
					} else if (name.equalsIgnoreCase("DNSName")) {
						elbInstance.setDnsName(value);
					} else if (name.equalsIgnoreCase("HealthCheck")) {
						Node p = properties.item(j).getFirstChild();
						Log.d("INTERVAL", name);
						do {
							if(p.getFirstChild() != null) {
								String _name = p.getNodeName();
								value = p.getFirstChild().getNodeValue();
								if (_name.equalsIgnoreCase("Interval")) {
									elbInstance.setHealthCheckInterval(value);
								} else if (_name.equalsIgnoreCase("Target")) {
									elbInstance.setHealthCheckTarget(value);
								} else if (_name.equalsIgnoreCase("HealthyThreshold")) {
									elbInstance.setHealthCheckHealthyThreshold(value);
								} else if (_name.equalsIgnoreCase("Timeout")) {
									elbInstance.setHealthCheckTimeout(value);
								} else if (_name.equalsIgnoreCase("UnhealthyThreshold")) {
									elbInstance.setHealthCheckUnhealthyThreshold(value);
								}
							}
						} while((p = p.getNextSibling()) != null);
					} else if (name.equalsIgnoreCase("Instances")) {
						
						NodeList members =  ((Element) property).getElementsByTagName("InstanceId");
						for(int k=0; k < members.getLength(); k++) {
							Node p = members.item(k).getFirstChild();
							elbInstance.getInstances().add(p.getNodeValue());
						}
						
					} else if (name.equalsIgnoreCase("Listeners")) {
						NodeList members =  ((Element) property).getElementsByTagName("member");
						for(int k=0; k < members.getLength(); k++) {
							Node p = members.item(k).getFirstChild();
							
							ElbPortConfiguration portConfig = new ElbPortConfiguration();
							
							do {
								if(p.getFirstChild() != null) {
									String _name = p.getNodeName();
									value = p.getFirstChild().getNodeValue();
									if (_name.equalsIgnoreCase("Protocol")) {
										portConfig.setProtocol(value);
									} else if (_name.equalsIgnoreCase("LoadBalancerPort")) {
										portConfig.setElbPort(value);
									} else if (_name.equalsIgnoreCase("InstancePort")) {
										portConfig.setInstancePort(value);
									}
								}
							} while((p = p.getNextSibling()) != null);
							
							elbInstance.getPortCongiguration().add(portConfig);
						}
					} else if (name.equalsIgnoreCase("ListenerDescriptions")) {
						elbInstance.setListenerDescriptions(value);
					} else if (name.equalsIgnoreCase("LoadBalancerName")) {
						elbInstance.setLoadBalancerName(value);
					} else if (name.equalsIgnoreCase("Policies")) {
						elbInstance.setPolicies(value);
					} else if (name.equalsIgnoreCase("SourceSecurityGroup")) {
						elbInstance.setSourceSecurityGroup(value);
					}
				}

				RdsDbInstances.add(elbInstance);
			}
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return RdsDbInstances;
	}
	
	public List<ElbInsanceState> describeInstanceHealth(String loadBalancerName) throws AwsRequestException {
		List<ElbInsanceState> elbInstancesStates = new ArrayList<ElbInsanceState>();
		
		params.put("Action", "DescribeInstanceHealth");
		params.put("LoadBalancerName", loadBalancerName);
		Element root = this.execute();
		
		XPath xpath = XPathFactory.newInstance().newXPath();
		
		try {
			NodeList items = (NodeList) xpath.evaluate("//InstanceStates/*", root,
					XPathConstants.NODESET);
			
			for (int i = 0; i < items.getLength(); i++) {
				ElbInsanceState elbInstanceState = new ElbInsanceState();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
				
				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();
					if (property.getFirstChild() == null)
						continue;
					String value = property.getFirstChild().getNodeValue();
					
					if (name.equalsIgnoreCase("Description")) {
						elbInstanceState.setDescription(value);
					} else if (name.equalsIgnoreCase("InstanceId")) {
						elbInstanceState.setInstanceId(value);
					} else if (name.equalsIgnoreCase("ReasonCode")) {
						elbInstanceState.setReasonCode(value);
					} else if (name.equalsIgnoreCase("State")) {
						elbInstanceState.setState(value);
					}
				}
				
				elbInstancesStates.add(elbInstanceState);
			}
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		
		return elbInstancesStates;
	}
	
	public void deregisterInstancesFromLoadBalancer(String elbName, String[] instances) {
		try {
			this.params.put("Action", "DeregisterInstancesFromLoadBalancer");
			this.params.put("LoadBalancerName", elbName);
			
			for(int i=0; i< instances.length; i++)
				this.params.put(String.format("Instances.member.%s", i+1), instances[i]);
			
		
			this.execute();
			
		} catch (AwsRequestException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void registerInstancesWithLoadBalancer(String elbName, String[] instances) {
		try {
			this.params.put("LoadBalancerName", elbName);
			this.params.put("Action", "RegisterInstancesWithLoadBalancer");
			
			for(int i=0; i< instances.length; i++)
				this.params.put(String.format("Instances.member.%s", i+1), instances[i]);
			
			this.execute();
		} catch (AwsRequestException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
